<template>

    <div class="mockups-download">
        <button @click="openDialog()">Download mockups</button>

        <UxDialog class="mockups-dialog" :visible="visible" :full-screen="true">
            <!-- 预览 -->
            <div class="mockups-choose">

                <h3>
                    <strong>Choose images</strong>
                    <span>Select the images to display in your store.</span>
                </h3>
                <!-- 选中 -->
                <div class="mockups-choose-scroller">
                    <h4 v-text="detail.title"></h4>
                    <dl v-for="(item) in classify" :key="item.model_tag">
                        <dt><span v-text="item.model_name || getTagName(item.model_tag)"></span></dt>
                        <dd>
                            <div class="mockups-choose-mockup">
                                <div class="mockups-choose-mockup-warp" v-for="model in item.models" :key="model.id" @click="setModel(item,model)">
                                    <CommonTemplatePreview :baseModel="model" :baseColor="getBaseColor(item.color_id)" size="largest" :class="{active:item.model_id == model.id}" />
                                </div>
                            </div>

                            <div class="mockups-choose-colors">
                                <blockquote v-for="color in colorList" :key="color.color_id" @click="setActive(item.model_id,color.color_id)">
                                    <CommonColorBlock :color="color" :active="!!selectAble.find(i=>i.color_id == color.color_id && i.model_id == item.model_id && i.select)" />
                                </blockquote>
                            </div>
                        </dd>
                    </dl>
                </div>

            </div>

            <!-- 选择图片 -->
            <div class="mockups-selected">
                <h3>
                    <strong>Images selected</strong>
                    <span v-text="selectAble.length"></span>
                </h3>
                <div class="mockups-selected-wapper">
                    <div class="mockups-selected-scroller" :count="selectAble.length">
                        <blockquote v-for="item in selectAble" :key="item.model_id + item.color_id">
                            <CommonTemplatePreview :baseModel="getBaseModel(item.model_id)" :baseColor="getBaseColor(item.color_id)" size="largest" />
                            <del @click="item.select = false"><svg-icon name="remove" /></del>
                        </blockquote>
                    </div>
                    <div class="mockups-selected-nodata" v-if="selectAble.length == 0">
                        <svg-icon name="user-template" />
                    </div>
                </div>

                <h3><strong>Format:</strong></h3>
                <ul class="detail-format">
                    <li @click="fileFormat = 'jpg'" :class="{active:fileFormat == 'jpg'}"><em>JPG</em> (Smaller file size; Store loads faster)</li>
                    <li @click="fileFormat = 'png'" :class="{active:fileFormat == 'png'}"><em>PNG</em> (Bigger file size; higher-quality image)</li>
                </ul>

                <!-- 下载按钮 -->
                <div class="detail-action">
                    <button type="primary" :class="{disabled: !fileFormat || selectAble.length == 0}" @click="beforeDownloadMockup()">Download</button>
                </div>

            </div>

        </UxDialog>

        <!-- 下载进度弹窗 -->
        <UxDialog :visible="!!downloading" class="detail-downloading" :can-close="false">
            <el-progress type="circle" color="#ea4c89" :percentage="downloading" :width="96"></el-progress>
            <p>Downloading</p>
        </UxDialog>
    </div>

</template>
<script>
import JSZip from "jszip";
import FileSaver from "file-saver";
export default {
    props: {
        detail: { type: Object, default: () => ({}) },
    },
    data () {
        return {
            visible: false,
            fileFormat: '',
            downloading: 0,
            classify: [],
            select: [],
        };
    },
    computed: {
        colorList () {
            const detail = this.detail || {}
            return detail.color_list || []
        },

        modelList () {
            const detail = this.detail || {}
            return detail.model_img || []
        },

        selectAble () {
            return this.select.filter(i => i.select)
        }

    },


    methods: {

        openDialog () {

            const detail = this.detail || {}
            const models = detail.model_img || [];
            const colors = detail.color_list || [];
            const select = [];
            const result = [
                { model_tag: 'hanging', model_name: '', model_id: '', color_id: '', models: [] },
                { model_tag: 'flat lay', model_name: '', model_id: '', color_id: '', models: [] },
                { model_tag: 'model', model_name: '', model_id: '', color_id: '', models: [] },
            ]
            result.map(item => {
                item.models = models.filter(m => (m.model_tag || 'hanging') == item.model_tag)
                item.models.map(model => colors.map(color => select.push({ model_id: model.id, color_id: color.color_id, select: false })))
                item.model_id = (item.models[0] || {}).id;
                item.model_name = (item.models[0] || {}).model_name;
            })

            select[0] && (select[0].select = true);

            this.visible = true;
            this.classify = result.filter(item => item.models.length > 0)
            this.select = select;

        },

        setModel (item, model) {
            item.model_id = model.id
        },

        // 选中
        setActive (model_id, color_id) {
            const active = this.select.find(i => i.model_id == model_id && i.color_id == color_id)
            if (active) {
                active.select = !active.select
            }

        },

        // 标签
        getTagName (tag) {
            const list = new Map([
                ['hanging', 'Hanging'],
                ['flat lay', 'Flat lay'],
                ['model', 'Model'],
            ])
            return list.get(tag) || 'Hanging'

        },

        // 选中的颜色
        getBaseColor (color_id) {
            const detail = this.detail || {}
            const color_list = detail.color_list || []
            const select = color_list.find(color => color.color_id == color_id);
            return select || color_list[0];
        },

        // 选中的颜色
        getBaseModel (model_id) {
            const detail = this.detail || {}
            const model_img = detail.model_img || []
            const select = model_img.find(model => model.id == model_id);
            return select || model_img[0];
        },

        // 下载前验证
        beforeDownloadMockup () {
            if (this.selectAble.length == 0) {
                this.$uxMessage.error('Unable to download as no image is selected.')
            } else if (!this.fileFormat) {
                this.$uxMessage.error('Unable to download as no image format is selected.')
            } else {
                this.downloadMockup()
            }

        },

        // 下载
        downloadMockup () {
            const promises = [];
            const modelObj = Object.fromEntries(this.detail.model_img.map((i) => [i.id, i]));
            const colorObj = Object.fromEntries(this.detail.color_list.map((i) => [i.color_id, i]));
            const imageobj = {};

            // 进度
            const percent = {
                total: 0, // 至少有一步
                count: 0,
                timer: null,
                value: 0,
            }

            // 设置进度
            const setPercent = (init) => {

                if (!init) {
                    percent.count += 1;
                    percent.value = Math.max(1, Math.min(100, parseInt(100 * (percent.count / percent.total))));
                    this.downloading = percent.value
                } else {
                    //
                }

                let value = Math.max(1, Math.min(99, parseInt(100 * ((percent.count + 1) / percent.total))))

                if (percent.value >= value) {
                    percent.timer && clearTimeout(percent.timer);
                } else {
                    const time = parseInt(Math.random() * 1000)
                    percent.value += 1;
                    percent.timer && clearTimeout(percent.timer);
                    percent.timer = setTimeout(e => setPercent(true), time)
                    this.downloading = percent.value;
                }
            }

            // 下载图片
            const loadImage = (url) => {
                percent.total += 1;
                return new Promise((res, rej) => {
                    let count = 3;
                    const createImage = () => {

                        const img = new Image();
                        img.onload = () => {
                            imageobj[url] = img;
                            setPercent();
                            res(img);
                        };
                        img.onerror = (err) => {
                            count -= 1;
                            if (count > 0) {
                                setTimeout(createImage, 500);
                            } else {
                                // 加载多次都失败了
                                rej(err)
                            }
                        };

                        img.crossOrigin = "anonymous";
                        img.src = this.$getImageUrl(url, 'original');
                    }

                    createImage();
                })
            }

            // 生成模特图
            const makeImage = (zip, model, color, index) => {

                return new Promise(res => {
                    const modelImage = imageobj[model.model_url];

                    // const surface = (model.surface_name || '').toLowerCase();
                    // const name = (surface.match(/^\S+/g) || [])[0] || '';
                    // const taxture = color['bg_' + name] ? imageobj[color['bg_' + name]] : null;

                    const taxture = this.$modelColorTaxture(model, color)
                    const filetype = this.fileFormat;
                    const canvas = document.createElement('canvas');
                    const ctx = canvas.getContext("2d");

                    canvas.width = modelImage.width;
                    canvas.height = modelImage.height;


                    if (taxture && imageobj[taxture]) {
                        // 有纹理，画底图
                        ctx.drawImage(imageobj[taxture], 0, 0, imageobj[taxture].width, imageobj[taxture].height, 0, 0, canvas.width, canvas.height);
                    } else {
                        // 没有纹理，画底色
                        ctx.fillStyle = this.$modelBackgroundColor(color.color_num, model);
                        ctx.fillRect(0, 0, canvas.width, canvas.height);
                    }

                    // 画图
                    ctx.drawImage(modelImage, 0, 0, modelImage.width, modelImage.height, 0, 0, canvas.width, canvas.height);

                    // 推入压缩包
                    canvas.toBlob(function (blob) {
                        zip.file('Mannequin_Image' + index + '.' + filetype, blob);
                        setPercent();
                        res();
                    }, 'image/' + filetype);
                })
            }


            // 01.加载模特图片
            this.selectAble.map(select => {
                const model = modelObj[select.model_id] || {};
                const url = model.model_url || '';
                const color = this.getBaseColor(select.color_id)
                const taxture = this.$modelColorTaxture(model, color)

                url && promises.push(loadImage(url))
                taxture && promises.push(loadImage(taxture))

            })

            // // 02.下载颜色图片
            // this.colorSelect.map(id => {
            //     const color = colorObj[id] || {};
            //     color.bg_front && promises.push(loadImage(color.bg_front))
            //     color.bg_back && promises.push(loadImage(color.bg_back))
            // })



            // 开始下载
            // 添加生成的步骤
            percent.total += this.selectAble.length;
            percent.value = 1;
            this.downloading = percent.value;
            setPercent(true);


            // 03.生成图片
            Promise.all(promises).then(images => {
                const zip = new JSZip();
                let index = 0;

                const makes = this.selectAble.map(select => {
                    const model = modelObj[select.model_id] || {};
                    const color = colorObj[select.color_id] || {};
                    return makeImage(zip, model, color, ++index)
                });
                return Promise.all(makes).then(res => {
                    return Promise.resolve(zip.generateAsync({ type: "blob" }))
                })
            }).then(content => {
                // 05.下载
                FileSaver(content, "Mannequin_Images.zip");
                this.downloading = 0;
                this.$uxMessage.success('Successfully downloaded.')
            }).catch(error => {

                console.log(error);
                this.$uxMessage.error('Download failed. Please try again.')
                this.downloading = 0;
            })

        },


        // 关闭
        doClose (force) {
            if (!force && this.changed) {
                this.exit = true;
            } else {
                this.exit = false;
                this.$nextTick(() => this.$emit('input', null))
            }
        }

    },
    created () {

    },
};
</script>
<style lang="scss" scoped>
.mockups-download {
    button {
        height: 32px;
        white-space: nowrap;
    }
}
.mockups-dialog {
    &::v-deep .dialog-body {
        width: 100vw;
        height: 100vh;
        max-width: initial;
        max-height: initial;
        border-radius: 0;
        overflow: hidden;
        display: flex;
        background: #f6f6f6;
    }

    .mockups-preview {
        position: relative;
        height: 100%;
        width: 50%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        padding: 0 100px;
        background: #fff;
        left: -50%;
        pointer-events: none;
        transition: all ease-in 0.5s;

        & > .mockups-preview-warp {
            width: 100%;
            max-width: calc(100vh - 50px);
        }

        & > button {
            position: absolute;
            left: 24px;
            top: 50%;
            width: 52px;
            height: 52px;
            margin-top: -26px;
            background: #fcfcfa;
            opacity: 0.35;
            border: 1px solid #caccc7;
            border-radius: 50px;
            font-size: 24px;
            cursor: pointer;

            &.el-icon-arrow-right {
                left: auto;
                right: 24px;
            }

            &:hover {
                color: #ea4c89;
                opacity: 1;
            }

            &[disabled] {
                cursor: default;
                opacity: 0.8;
                border: 1px solid #ddd;
                color: #ccc;
            }
        }

        .sync-mockups-preview {
            border: none;
        }

        &[active] {
            left: 0;
            opacity: 1;
            pointer-events: all;
        }
    }

    .mockups-choose {
        position: relative;
        width: 50%;
        display: flex;
        padding: 32px 0;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        background-color: #f6f6f6;

        &::after {
            content: '';
            position: absolute;
            left: 100%;
            top: 50%;
            margin-top: -20px;
            border-style: solid;
            border-width: 20px 0 20px 16px;
            border-color: transparent transparent transparent #f6f6f6;
        }

        & > h3 {
            width: 100%;
            max-width: 562px;
            box-sizing: border-box;
            padding: 0 10px 8px;

            strong {
                display: block;
                font-size: 24px;
                font-family: Roboto-Medium, Roboto;
                font-weight: 500;
                color: #000000;
                line-height: 26px;
            }
            span {
                display: block;
                margin-top: 12px;
                font-size: 14px;
                font-family: Roboto-Regular, Roboto;
                font-weight: 400;
                color: #555555;
                line-height: 16px;
            }
        }

        .mockups-choose-scroller {
            width: 100%;
            max-width: 562px;
            margin-top: 23px;
            padding: 8px 10px;
            display: flex;
            flex-direction: column;
            box-sizing: border-box;
            overflow: auto;

            & > h4 {
                font-size: 14px;
                font-family: Roboto-Regular, Roboto;
                font-weight: 400;
                color: #000000;
                line-height: 18px;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }
        }

        dl {
            margin-top: 12px;
            background: #ffffff;
            border-radius: 6px;
            border: 1px solid #ebebeb;
            transition: all 0.3s;
            padding: 14px 16px 16px;
            dt {
                font-size: 12px;
                font-family: Roboto-Medium, Roboto;
                font-weight: 500;
                color: #555555;
                line-height: 14px;
            }

            dd {
                margin-top: 12px;
                display: flex;
                align-items: flex-start;
            }

            &:hover {
                box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.14);
                .template-preview {
                    &:hover {
                        &:after {
                            content: '';
                            position: absolute;
                            left: 0;
                            top: 0;
                            right: 0;
                            bottom: 0;
                            border-radius: 3px;
                            border: 1px solid #ebebeb;
                        }
                    }
                    &.active {
                        border-color: #f6b2cd;
                        &:after {
                            content: '';
                            position: absolute;
                            left: 0;
                            top: 0;
                            right: 0;
                            bottom: 0;
                            border-radius: 3px;
                            border: 1px solid #f6b2cd;
                        }
                    }
                }
            }
        }

        .mockups-choose-mockup {
            display: flex;
            flex-wrap: wrap;
            margin-left: -7px;
            margin-top: -7px;
            .mockups-choose-mockup-warp {
                padding: 7px;
            }

            .template-preview {
                width: 128px;
                height: 128px;
                background: #ffffff;
                border-radius: 4px;
                border: 1px solid #ebebeb;
                box-sizing: border-box;
                overflow: hidden;
                cursor: pointer;
                transition: all 0.3s;
            }
            & > button {
                width: 128px;
                height: 28px;
                font-size: 14px;
                margin-top: 12px;
                border-radius: 4px;
            }
        }

        .mockups-choose-colors {
            margin-left: 20px;
            display: flex;
            flex: 1;
            flex-wrap: wrap;
            position: relative;
            justify-content: flex-start;
            align-items: flex-start;
            padding-top: 26px;
            &::before {
                content: 'Color';
                position: absolute;
                left: 0;
                top: 0;
                font-size: 12px;
                font-family: Roboto-Medium, Roboto;
                font-weight: 500;
                color: #000000;
                line-height: 14px;
            }

            blockquote {
                margin: 0;
                padding: 0;
                margin-right: 8px;
                margin-bottom: 8px;
                cursor: pointer;
            }
        }
    }

    .mockups-selected {
        width: 50%;
        background: #fff;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        padding: 32px 0;

        & > h3 {
            display: flex;
            align-items: center;
            padding-top: 26px;
            font-family: Roboto-Medium, Roboto;
            line-height: 18px;
            width: 100%;
            max-width: 456px;

            strong {
                font-size: 16px;
                color: #000000;
                font-weight: 500;
            }
            span {
                margin-left: 4px;
                height: 16px;
                padding: 0 4px;
                background: #f6f6f6;
                border-radius: 4px;
                font-size: 12px;
                font-family: Roboto-Regular, Roboto;
                font-weight: 400;
                color: #555555;
                line-height: 16px;
            }

            svg {
                width: 14px;
                height: 14px;
                background-color: #ababab;
                fill: #fff;
                border-radius: 14px;
                cursor: pointer;
                margin-left: 6px;
            }
        }
    }

    .mockups-selected-wapper {
        margin: 16px 0 0;
        display: flex;
        position: relative;
        flex: 1;
        flex-direction: column;
        justify-content: flex-start;
        max-width: 472px;
        width: 100%;
        max-height: 440px;
        .mockups-selected-scroller {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            max-height: 100%;
            padding: 4px;
            box-sizing: border-box;
            overflow: auto;
            display: flex;
            flex-wrap: wrap;

            & > blockquote {
                width: calc(25% - 8px);
                margin: 4px;
                padding: 0;
                overflow: hidden;
                position: relative;
                border-radius: 4px;
                box-sizing: border-box;
                border: 1px solid #ebebeb;

                &::before {
                    content: '';
                    position: absolute;
                    left: 0;
                    top: 0;
                    width: 100%;
                    height: 100%;
                    padding: 0;
                    z-index: 1;
                    background-color: rgba(0, 0, 0, 0.2);
                    transition: opacity 0.5s;
                    opacity: 0;
                }

                & > a {
                    position: absolute;
                    z-index: 2;
                    left: 50%;
                    top: 50%;
                    transform: translate(-50%, -50%);
                    box-sizing: border-box;
                    white-space: nowrap;
                    padding: 0 6px;
                    height: 24px;
                    background: #ffffff;
                    border-radius: 12px;
                    font-size: 12px;
                    line-height: 24px;
                    font-family: Roboto-Regular, Roboto;
                    font-weight: 400;
                    color: #555555;
                    cursor: pointer;
                    opacity: 0;
                    transition: opacity 0.5s;
                    &:hover {
                        color: #ea4c89;
                    }
                }
                & > del {
                    position: absolute;
                    top: 6px;
                    right: 8px;
                    padding: 1px;
                    box-sizing: border-box;
                    background-color: #fff;
                    border-radius: 18px;
                    width: 16px;
                    height: 16px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    z-index: 2;
                    opacity: 0;
                    transition: opacity 0.5s;
                    cursor: pointer;
                    svg {
                        vertical-align: top;
                        width: 12px;
                        height: 12px;
                        color: #555;
                    }
                    &:hover svg {
                        fill: #ea4c89;
                    }
                }

                & > cite {
                    display: none;
                }

                &:hover {
                    &::before {
                        opacity: 1;
                    }
                    & > a {
                        opacity: 1;
                    }
                    & > del {
                        opacity: 1;
                    }
                }
            }
        }

        .mockups-selected-nodata {
            position: absolute;
            left: 8px;
            top: 0;
            right: 8px;
            bottom: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            color: #919191;
            border-radius: 4px;
            border: 1px solid #eaeaea;
            font-size: 12px;
            font-family: Roboto-Regular, Roboto;
            font-weight: 400;
            line-height: 12px;
            &::after {
                content: 'None';
            }

            svg {
                width: 48px;
                height: 48px;
                margin-bottom: 8px;
                fill: #d9d9d9;
            }
        }
    }

    .detail-format {
        width: 100%;
        max-width: 456px;
        margin-top: 18px;

        li {
            padding-left: 26px;
            position: relative;
            font-size: 12px;
            font-family: Roboto-Regular, Roboto;
            font-weight: 400;
            color: #000;
            line-height: 18px;
            cursor: pointer;

            &::before {
                content: '';
                position: absolute;
                left: 0;
                top: 50%;
                transform: translateY(-50%);
                width: 18px;
                height: 18px;
                border-radius: 18px;
                box-sizing: border-box;
                border: 2px solid #919191;
            }

            & + li {
                margin-top: 14px;
            }

            &.active::before {
                border-color: #ea4c89;
            }
            &.active::after {
                content: '';
                position: absolute;
                left: 6px;
                top: 50%;
                transform: translateY(-50%);
                width: 6px;
                height: 6px;
                border-radius: 6px;
                background: #ea4c89;
            }
        }
    }

    .detail-action {
        width: 100%;
        max-width: 456px;
        margin-top: 24px;
        display: flex;

        button {
            height: 38px;
            width: 160px;
            font-weight: bold;
        }
    }
}

.detail-downloading {
    &::v-deep .dialog-content {
        background: #ffffff;
        border-radius: 28px;
        .dialog-body {
            width: 320px;
            height: 320px;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            justify-content: center;
            align-items: center;
        }
    }

    .el-progress {
        width: 96px;
        height: 96px;

        &::v-deep {
            .el-progress-circle {
                width: 96px;
                height: 96px;
            }

            .el-progress__text {
                font-size: 20px;
                font-family: Roboto-Medium, Roboto;
                font-weight: 500;
                color: #000000;
            }
        }
    }
    p {
        margin-top: 24px;
        font-size: 14px;
        font-family: Roboto-Regular, Roboto;
        font-weight: 400;
        color: #000000;
        line-height: 16px;
    }
}
</style>
